<template>
  <el-card>
    <!-- 表格 -->
    <el-table :data="MenuList" row-key="id" v-loading="loading" :expand-row-keys="expandIds" border style="width: 100%">
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="code" label="权限值" />
      <el-table-column prop="toCode" label="跳转权限值" />
      <el-table-column label="操作" align="center">
        <template v-slot="{row}">
          <el-button type="primary" title="添加菜单" :icon="Plus" size="small" :disabled="row.level === 4" @click="SaveMenu(row)"></el-button>
          <el-button type="primary" title="修改菜单" :icon="Edit" size="small" :disabled="row.id === '1'" @click="updateMenu(row)"></el-button>
          <el-button type="danger" title="删除" :icon="Delete" size="small" @click="deleteFuncOrMenu(row.id)"></el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 新增菜单对话框 -->
    <el-dialog v-model="dialogFormVisible" :title="diglogTitle">
      <el-form :model="menuInfo" ref="ruleFormRef" :rules="permissionRules" style="width: 90%" label-width="130px">
        <el-form-item prop="name" label="名称">
          <el-input v-model="menuInfo.name" />
        </el-form-item>
        <el-form-item prop="code" label="功能权限值">
          <el-input v-model="menuInfo.code" />
        </el-form-item>
        <el-form-item v-if="menuInfo.level === 4" label="跳转路由权限值">
          <el-input v-model="menuInfo.toCode" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="saveOrUpdateMenu()"
            >确定</el-button
          >
        </span>
      </template>
    </el-dialog>

  </el-card>
</template>
<script lang="ts">
export default {
  name: 'Permission'
}
</script>
<script lang="ts" setup>
import {ref, onMounted, computed, reactive, nextTick} from 'vue'
// 引入图标组件
import { Search, Delete, Edit, Plus } from '@element-plus/icons-vue'
// 引入消息提示组件
import {ElMessage, ElMessageBox} from 'element-plus'
// 引入类型
import type { FormInstance, FormRules } from 'element-plus'
// 引入权限相关的接口类型
import type {ResMenuListModel, MenuListModel, MenuInfoModel, PermissionLevelModel} from '@/api/acl/model/permissionModel'
// 引入权限相关的接口函数
import {getMenuApi, saveOrUpdateMenuApi, recursionDeleteMenuApi} from '@/api/acl/permission'

const loading = ref<boolean>(false) // 载入效果的标识
const MenuList = ref<MenuListModel>([]) // 定义存储菜单对象数组
const dialogFormVisible = ref<boolean>(false) // 编辑菜单对话框显示标识
// 定义初始化菜单对象
const initMenuInfo = ():MenuInfoModel => ({
  id: undefined,
  name: '',
  code: '',
  type: 1,
  toCode: '',
  pid: ''
})
const menuInfo = ref<MenuInfoModel>(initMenuInfo()) // 定义菜单对象
const ruleFormRef = ref<FormInstance>() // 定义获取表单实例对象

// 计算属性 对话框 title
const diglogTitle = computed(() => {
  if (!menuInfo.value.id) {
    return menuInfo.value.level === 4? '新增功能': '添加菜单'
  } else {
    return menuInfo.value.level === 4? '修改功能': '修改菜单'
  }
})
// 计算属性 校验规则
const permissionRules = computed(() => {
  // 定义操作菜单的校验规则
  const MenuRules = reactive<FormRules>({
    name: [
      { required: true, message: '请输入菜单名称', trigger: 'blur' },
      { min: 2, max: 20, message: '菜单名称长度为2-20', trigger: 'blur' },
    ],
    code: [
      { required: true, message: '请输入功能权限值', trigger: 'blur' },
    ]
  })
  // 定义操作菜单的校验规则
  const functionRules = reactive<FormRules>({
    name: [
      { required: true, message: '请输入功能名称', trigger: 'blur' },
      { min: 2, max: 20, message: '功能名称长度为2-20', trigger: 'blur' },
    ],
    code: [
      { required: true, message: '请输入功能权限值', trigger: 'blur' },
    ]
  })    
  return menuInfo.value.level === 4? functionRules: MenuRules
})

// 定义获取权限菜单列表的方法
const getPermissionList = async () => {
  loading.value = true
  const {children} = await getMenuApi()
  loading.value = false
  // 更新列表数据
  MenuList.value = children
}
// 添加菜单
const SaveMenu = (row: MenuInfoModel) => {
  // 显示对话框
  dialogFormVisible.value = true
  // 初始化数据
  menuInfo.value = initMenuInfo()
  if (row.level) {
    menuInfo.value.level = (row.level + 1) as PermissionLevelModel // level + 1 因为是添加子菜单
    menuInfo.value.type = (row.level + 1) === 4 ? 2: 1 // 判断是否添加功能
  }
  menuInfo.value.pid = row.id // pid为父级id
  // 清除校验(必须在界面更新之后)
  // 注意: 校验规则是动态的, nextTick清除后还会显示错误信息, 应该是在nextTick后进行了校验
  setTimeout(() => {
    ruleFormRef.value?.clearValidate()
  }, 0)
}
// 修改菜单
const updateMenu = (row: MenuInfoModel) => {
  // 清除校验信息
  ruleFormRef.value?.clearValidate()
  // 错误行为 不能直接赋值 
  // menuInfo.value = row 
  Object.assign(menuInfo.value, row)
  // 显示对话框
  dialogFormVisible.value = true
}
// 添加或修改菜单回调
const saveOrUpdateMenu = async () => {
  // 表单整体校验
  ruleFormRef.value?.validate(async (valid) => {
    // 校验失败
    if (!valid) return 
    // 校验成功
    try {
      // 调用接口
      await saveOrUpdateMenuApi(menuInfo.value)
      // 成功提示
      ElMessage.success('操作成功')
      // 关闭对话框
      dialogFormVisible.value = false
      // 重新渲染列表
      getPermissionList()
    } catch (error: any) {
      ElMessage.warning(error.message)
    }
  })
}
// 移除功能或菜单的回调
const deleteFuncOrMenu = async (id: string) => {
  ElMessageBox.confirm(
    `此操作不可逆，确定执行删除操作吗？`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(async () => {
      await recursionDeleteMenuApi(id)
      // 更新列表数据 重新渲染
      getPermissionList()
      ElMessage({
        type: 'success',
        message: '删除成功',
      })

    })
    .catch(() => {
      ElMessage({
        type: 'warning',
        message: '取消删除',
      })
    })
}

// 组件挂载完成
onMounted(() => {
  getPermissionList()
})


// 计算属性 用于产生自动展开行的id数组(已弃用)
const expandIds = computed(() => {
  return MenuList.value.map(item => item.id)
})
// 计算属性 跳转路由权限值是否显示（已弃用）
const toCodeIsShow = computed(() => {
  if (menuInfo.value.level === 4) return true
  return false
})
</script>
<style scoped>
</style>